
/**
 * @file:       thread_time.hpp
 * @author:     WubinWang
 * @contact:    wubinstu@163.com
 * @date:       2025-01-01
 * @license:    MIT License
 *
 * Copyright (c) 2025 WubinWang
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 * DISCLAIMER:
 * 1. User acknowledges all application risks and consequences arising from usage
 *    of this software are exclusively borne by the user.
 * 2. The original author shall not be held liable for any direct, indirect,
 *    incidental, special, exemplary or consequential damages.
 * 3. No warranty of fitness for particular purpose or non-infringement is provided. */


#ifndef __THREAD_TIME_HPP_
#define __THREAD_TIME_HPP_

#include <cstdint>

#if defined(_WIN32)
#include <windows.h>
#elif defined(__linux__)
#include <time.h>
#else
#error "Unsupported platform"
#endif

inline auto GetThreadCpuTimeUs () noexcept -> std::int64_t {
#if defined(_WIN32)
    FILETIME createTime, exitTime, kernelTime, userTime;
    if (GetThreadTimes (GetCurrentThread (), &createTime, &exitTime, &kernelTime, &userTime)) {
        // 将 FILETIME 结构转换为64位整数
        ULARGE_INTEGER user, kernel;
        user.LowPart    = userTime.dwLowDateTime;
        user.HighPart   = userTime.dwHighDateTime;
        kernel.LowPart  = kernelTime.dwLowDateTime;
        kernel.HighPart = kernelTime.dwHighDateTime;

        // Windows时间单位为100纳秒, 转换为微秒需要除以10
        return static_cast<std::int64_t> ((user.QuadPart + kernel.QuadPart) / 10);
    }
#elif defined(__linux__)
    struct timespec ts;
    if (clock_gettime (CLOCK_THREAD_CPUTIME_ID, &ts) == 0) {
        return static_cast<std::int64_t> (ts.tv_sec) * 1000000 + static_cast<std::int64_t> (ts.tv_nsec) / 1000;  // 秒转换为微秒 + 纳秒转换为微秒
    }
#endif
    return -1;
}

#endif
